`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/06/26 11:49:23
// Design Name: 
// Module Name: mem
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module mem(
    input clk,
    input rst,
    input [31:0] adr,
    input [31:0] wdin,
    input dram_we,
    input [2:0] dram_op,
    output reg [31:0] rd
    );

wire [1:0]  offset = adr[1:0];  
wire [31:0] dout;   
wire [31:0] bin = (offset == 2'b00)? {dout[31:8],wdin[7:0]}:
                  (offset == 2'b01)? {dout[31:16],wdin[7:0],dout[7:0]}:
                  (offset == 2'b10)? {dout[31:24],wdin[7:0],dout[15:0]}:
                                     {wdin[7:0],dout[23:0]};
wire [31:0] hwin = (offset[1] == 1'b0)? {dout[31:16],wdin[15:0]}:
                                        {wdin[15:0],dout[15:0]};
wire [31:0] din = (dram_op == `B) ? bin: 
                  (dram_op == `HW)? hwin:
                  (dram_op == `W) ? wdin: 32'hzzzzzzzz;   
wire [7:0]  byte = (offset == 2'b00)? dout[7:0]:
                   (offset == 2'b01)? dout[15:8]:
                   (offset == 2'b10)? dout[23:16]:dout[31:24];
wire [15:0] half_word = (offset[1] == 1'b0)? dout[15:0]:
                                             dout[31:16];
wire [31:0] wadr = adr;// - 16'h4000;
    
dram dram_0(.clk    (clk),            // input wire clka
            .a      (wadr[15:2]),     // input wire [13:0] addra
            .spo    (dout),           // output wire [31:0] douta
            .we     (dram_we),        // input wire [0:0] wea
            .d      (din)             // input wire [31:0] dina
           );    

always @(*)
begin
    if (rst)
    begin
        rd <= 32'hzzzzzzzz;
    end 
    else
    begin
        case (dram_op)
            `B:      rd <= {{24{byte[7]}},byte};
            `BU:     rd <= {{24{1'b0}},byte};
            `HW:     rd <= {{16{half_word[15]}},half_word};
            `HWU:    rd <= {{16{1'b0}},half_word};
            `W:      rd <= dout;
            default: rd <= 32'hzzzzzzzz;
        endcase    
    end       
end
    
endmodule
